home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / What's New? / Development Kits / Mac OS / USB DDK 1.4.6f4 / Examples / USBModem / ShimSerialHAL.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-25  |  21.1 KB  |  917 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        ShimSerialHAL.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Copyright:    © 1998-2000 by Apple Computer, Inc., all rights reserved.
  9.  
  10. */
  11.  
  12. #include    <Gestalt.h>
  13. #include    <Errors.h>
  14.  
  15. #include    "Modem.h"
  16. #include    "ModemVersion.h"
  17. #include    "ShimSerialHAL.h"
  18. #include    "ModemDriver.h"
  19.  
  20. /************************************************************************************/
  21. //
  22. //    SerHAL_Entry
  23. //
  24. //    This is the main driver entry point.
  25. //
  26. /************************************************************************************/
  27.  
  28. OSErr SerHAL_Entry(UInt16 HdwSelector, ParmBlkPtr pb, UInt32 RefCon)
  29. {
  30. #pragma unused (RefCon)
  31.     OSErr    err = noErr;
  32.     
  33.     switch (HdwSelector)
  34.         {
  35.             case SerHAL_Initialize:
  36.                 // only do the open stuff once per driver pair
  37.                 if (gGlobals->openSession == false)
  38.                      err = HAL_DoOpenSession();
  39.                 break;
  40.                 
  41.             case SerHAL_Terminate:
  42.                 // only do the close stuff once per driver pair
  43.                 if (gGlobals->openSession)
  44.                     err = HAL_DoCloseSession();
  45.                 break;
  46.                 
  47.             case SerHAL_Read:
  48.                 //    attempt to fill read request immediately
  49.                 //    from any pending data in the input buffer
  50.                 err = HAL_FillReadRequest((IOParam*)pb);
  51.                 HAL_InputFlowControl();
  52.                 //    if it's not completed (pending) save the pb
  53.                 if (err > noErr)
  54.                     gGlobals->pbIn = pb;
  55.                 break;
  56.                 
  57.             case SerHAL_Write:
  58.                 err = USBSerialWrite((IOParam*)pb);
  59.                 if (err > noErr)
  60.                     gGlobals->pbOut = pb;
  61.                 break;
  62.                 
  63.             case SerHAL_SetConfiguration:
  64.                 err = HAL_SetConfiguration(*(UInt16*)pb->cntrlParam.csParam);
  65.                 break;
  66.                 
  67.             case SerHAL_SetInputBuffer:
  68.                 err = HAL_SetInputBuffer(*(Ptr*)pb->cntrlParam.csParam, *(UInt16*)(((Ptr)pb->cntrlParam.csParam) + 4));
  69.                 break;
  70.                 
  71.             case SerHAL_SetFlowControl:
  72.                 HAL_SetFlowControl((SerShk*)pb->cntrlParam.csParam, pb->cntrlParam.csCode);
  73.                 break;
  74.                 
  75.             case SerHAL_SetBreak:
  76.                 USBSendBreak((pb->cntrlParam.csCode == kSERDSetBreak));
  77.                 break;
  78.                 
  79.             case SerHAL_SetDTERate:
  80.                 // check csCode first to see what the real rate is
  81.                 if (pb->cntrlParam.csCode == kSERD115KBaud)
  82.                 {
  83.                     *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(115200);
  84.                 } else {
  85.                     if (pb->cntrlParam.csCode == kSERD230KBaud)
  86.                     {
  87.                         *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(230400);
  88.  
  89.                     } else {
  90.                         *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(*(UInt16*)pb->cntrlParam.csParam);
  91.                     }
  92.                 }            
  93.                 break;
  94.                 
  95.             case SerHAL_SetDTR:
  96.                 USBSetDTRState((pb->cntrlParam.csCode == kSERDAssertDTR));
  97.                 USBSetControlLineState();
  98.                 break;
  99.                 
  100.             case SerHAL_SetParity:
  101.                 HAL_SetParity((pb->cntrlParam.csCode == kSERDSetPEAltChar), *(unsigned char*)pb->cntrlParam.csParam, *(((unsigned char*)pb->cntrlParam.csParam)+1));
  102.                 break;
  103.                 
  104.             case SerHAL_SetXOffFlag:
  105.                 HAL_SetXOffFlag(pb->cntrlParam.csCode == kSERDSetXOffFlag);
  106.                 break;
  107.                 
  108.             case SerHAL_SendXOn:
  109.                 HAL_SendXOn((pb->cntrlParam.csCode == kSERDSendXOn));
  110.                 break;
  111.                 
  112.             case SerHAL_SendXOff:
  113.                 HAL_SendXOff((pb->cntrlParam.csCode == kSERDSendXOff));
  114.                 break;
  115.                 
  116.             case SerHAL_Miscellaneous:
  117.                 // only interested in DTR (for now)
  118.                 if ((UInt8)pb->cntrlParam.csParam[0] & kOptionPreserveDTR) 
  119.                 {
  120.                     USBSetCloseDTR();
  121.                 }
  122.                 break;
  123.                 
  124.             case SerHAL_GetBuffer:
  125.                 *(UInt32*)(&pb->cntrlParam.csParam[0]) = HAL_GetBuffer();
  126.                 break;
  127.                 
  128.             case SerHAL_GetStatus:
  129.                 HAL_GetStatus((SerStaRec*)pb->cntrlParam.csParam);
  130.                 break;
  131.                 
  132.             case SerHAL_GetVersion:
  133.                 *(char *)pb->cntrlParam.csParam = DriverVersion;
  134.                 break;
  135.                 
  136.             case SerHAL_ControlExtend:
  137.                 err = HAL_ControlExtend(pb);
  138.                 break;
  139.                 
  140.             case SerHAL_StatusExtend:
  141.                 err = HAL_StatusExtend(pb);
  142.                 break;
  143.                 
  144.             case SerHAL_KillRead:
  145.                 gGlobals->pbIn = nil;    // Device Manager handles I/O queue
  146.                 break;
  147.                 
  148.             case SerHAL_KillWrite:
  149.                 gGlobals->pbOut = nil;    // Device Manager handles I/O queue
  150.                 break;
  151.                 
  152.             default:
  153.                 err = -1;                // unknown selector (for now)
  154.                 break;
  155.         }
  156.     
  157.     return err;
  158. }
  159.  
  160. /************************************************************************************/
  161. //
  162. //    HAL_SetConfiguration
  163. //
  164. //    Serial driver SerReset control call.
  165. //
  166. /************************************************************************************/
  167.  
  168. OSErr HAL_SetConfiguration(UInt16 config)
  169. {
  170.  
  171.     UInt16        baudRate;
  172.     LineParms    Line_Coding;
  173.  
  174.     TraceMessage(0,kCRMName"- Entering HAL_SetConfiguration");
  175.     
  176.     switch (config & kSerConfigBaudMask)
  177.     {
  178.         case baud300: baudRate = 300; break;
  179.         case baud600: baudRate = 600; break;
  180.         case baud1200: baudRate = 1200; break;
  181.         case baud1800: baudRate = 1800; break;
  182.         case baud2400: baudRate = 2400; break;
  183.         case baud3600: baudRate = 3600; break;
  184.         case baud4800: baudRate = 4800; break;
  185.         case baud7200: baudRate = 7200; break;
  186.         case baud9600: baudRate = 9600; break;
  187.         case baud19200: baudRate = 19200; break;
  188.         case baud38400: baudRate = 38400; break;
  189.         case baud57600: baudRate = 57600; break;
  190.         default: baudRate = 57600; break;
  191.     }
  192.         
  193.     Line_Coding.DTERate1 = USBToHostWord(baudRate);        // All because of Intel format
  194.     Line_Coding.DTERate2 = 0;
  195.     
  196.     switch (config & kSerConfigLenMask)
  197.     {
  198.         case data5: 
  199.             Line_Coding.DataBits = k5DataBits;
  200.             break;
  201.         case data6: 
  202.             Line_Coding.DataBits = k6DataBits;
  203.             break;
  204.         case data7: 
  205.             Line_Coding.DataBits = k7DataBits;
  206.             break;
  207.         case data8: 
  208.             Line_Coding.DataBits = k8DataBits;
  209.             break;
  210.         default: 
  211.             Line_Coding.DataBits = k8DataBits;
  212.             break;
  213.     }
  214.     
  215.     switch (config & kSerConfigParityMask)
  216.     {
  217.         case noParity: 
  218.             Line_Coding.ParityType = kNoParity;
  219.             break;
  220.         case oddParity: 
  221.             Line_Coding.ParityType = kOddParity;
  222.             break;
  223.         case evenParity: 
  224.             Line_Coding.ParityType = kEvenParity;
  225.             break;
  226.         default: 
  227.             Line_Coding.ParityType = kNoParity;
  228.             break;
  229.     }
  230.     
  231.     switch (config & kSerConfigStopMask)
  232.     {
  233.         case stop10: 
  234.             Line_Coding.CharFormat = k1StopBit;
  235.             break;
  236.         case stop15: 
  237.             Line_Coding.CharFormat = k15StopBits;
  238.             break;
  239.         case stop20: 
  240.             Line_Coding.CharFormat = k2StopBits;
  241.             break;
  242.         default: 
  243.             Line_Coding.CharFormat = k1StopBit;
  244.             break;
  245.     }
  246.     
  247.     //    reset the baud rate and other values
  248.  
  249.     USBSetLineCoding(Line_Coding);
  250.  
  251.     return noErr;
  252. }
  253.  
  254. /************************************************************************************/
  255. //
  256. //    HAL_SetInputBuffer
  257. //
  258. //    Select and initialize the serial input buffer.
  259. //
  260. /************************************************************************************/
  261.  
  262. OSErr HAL_SetInputBuffer(Ptr newBuf, UInt16 bufLen)
  263. {
  264.     OSErr    err;
  265.     long    result;
  266.     Boolean    vmPresent;
  267.         
  268.     TraceMessage(0,kCRMName"- Entering HAL_SetInputBuffer");
  269.     
  270.     //  check for presence of virtual memory
  271.     
  272.     err = Gestalt(gestaltVMAttr,&result);
  273.     vmPresent = ((err == noErr) && (result >= gestaltVMPresent));
  274.     
  275.     //  un-hold any previous input buffer
  276.     
  277.     if (vmPresent && gGlobals->inBufPtr && (gGlobals->inBufPtr != gGlobals->builtInBuffer))
  278.         UnholdMemory(gGlobals->inBufPtr, gGlobals->inBufLen);
  279.     
  280.     //    assign our local buffer as the default
  281.     
  282.     gGlobals->inBufPtr = gGlobals->builtInBuffer;
  283.     gGlobals->inBufLen = kBuiltInBufferSize;
  284.     
  285.     //    reset buffer indexes
  286.     
  287.     gGlobals->inBufStartIndex = 0;
  288.     gGlobals->inBufEndIndex = 0;
  289.         
  290.     //    a non-zero buffer length means use client buffer
  291.     //    a zero buffer length means use the default buffer
  292.     
  293.     if (bufLen && newBuf)
  294.     {
  295.         //  we need to make sure the buffer stays in physical memory
  296.         
  297.         if (vmPresent)
  298.         {
  299.             err = HoldMemory(newBuf, bufLen);
  300.             if (err != noErr)
  301.                 return err;
  302.         }
  303.         
  304.         //    assign client buffer
  305.         gGlobals->inBufPtr = (UInt8 *) newBuf;
  306.         gGlobals->inBufLen = bufLen;
  307.     }
  308.     
  309.     return noErr;
  310. }
  311.  
  312. /************************************************************************************/
  313. //
  314. //    HAL_SetFlowControl
  315. //
  316. //    Process the csSerHShake & csSerHShakeDTR control calls.
  317. //
  318. /************************************************************************************/
  319.  
  320. void HAL_SetFlowControl(SerShk *shkNew, UInt16 csCode)
  321. {
  322.     
  323.     TraceMessage(0,kCRMName"- Entering HAL_SetFlowControl");
  324.     
  325.     //
  326.     //    set new cts value
  327.     //
  328.  
  329.     gGlobals->serShk.fCTS = shkNew->fCTS;
  330.  
  331.     //
  332.     //    copy over new xon / xoff characters
  333.     //
  334.  
  335.     gGlobals->serShk.xOn = shkNew->xOn;
  336.     gGlobals->serShk.xOff = shkNew->xOff;
  337.  
  338.     //
  339.     //    handle any change in software output flow control
  340.     //    this is ignored for now
  341.  
  342.     gGlobals->serShk.fXOn = 0;
  343.  
  344.     //    copy over the errs & evts options fields
  345.     //    notice we do _nada_ with the events (no _PostEvent, etc.)
  346.     
  347.     gGlobals->serShk.errs = shkNew->errs & (parityErr | hwOverrunErr | framingErr);
  348.     gGlobals->serShk.evts = shkNew->evts;
  349.  
  350.     //    handle any change in software input flow control
  351.     //    again this is ignored for now
  352.  
  353.     gGlobals->serShk.fInX = 0;
  354.  
  355.     //    if csCode is newer kSERDHandshake,
  356.     //    take account of the fDTR field
  357.  
  358.     if (csCode == kSERDHandshake)
  359.     {
  360.         
  361.         //
  362.         //    handle any change in hardware input flow control
  363.         //    ignored for now
  364.         //
  365.  
  366.         gGlobals->serShk.fDTR = 1;
  367.  
  368.     }
  369. }
  370.  
  371. /************************************************************************************/
  372. //
  373. //    HAL_SendXOn
  374. //
  375. //    Determines whether to send XOn character.
  376. //    This is a stub for now
  377. //
  378. /************************************************************************************/
  379.  
  380. void HAL_SendXOn(Boolean always)
  381. {
  382. #pragma unused (always)
  383.  
  384.     TraceMessage(0,kCRMName"- Entering HAL_SendXOn");
  385.     
  386. }
  387.  
  388. /************************************************************************************/
  389. //
  390. //    HAL_SendXOff
  391. //
  392. //    Determines whether to send XOff character.
  393. //    This is a stub for now
  394. //
  395. /************************************************************************************/
  396.  
  397. void HAL_SendXOff(Boolean always)
  398. {
  399. #pragma unused (always)
  400.  
  401.     TraceMessage(0,kCRMName"- Entering HAL_SendXOff");
  402.  
  403. }
  404.  
  405. /************************************************************************************/
  406. //
  407. //    HAL_SendXOffFlag
  408. //
  409. //    Determines whether to send XOff character.
  410. //
  411. /************************************************************************************/
  412.  
  413. void HAL_SetXOffFlag(Boolean state)
  414. {
  415. #pragma unused (state)
  416.  
  417.     TraceMessage(0,kCRMName"- Entering HAL_SetXOffFlag");
  418.     
  419.     gGlobals->serStat.xOffHold = 0;            // always off for now
  420.     
  421. }
  422.  
  423. /************************************************************************************/
  424. //
  425. //    HAL_GetStatus
  426. //
  427. //    Status routine fills in the SerStaRec record.
  428. //
  429. /************************************************************************************/
  430.  
  431. void HAL_GetStatus(SerStaRec *statRec)
  432. {
  433.     
  434.     TraceMessage(0,kCRMName"- Entering HAL_GetStatus");
  435.     
  436.     //    get & reset cumErrs
  437.     
  438.     statRec->cumErrs = gGlobals->serStat.cumErrs;
  439.     gGlobals->serStat.cumErrs = 0;
  440.  
  441.     //    has an xOff been sent to stop input?
  442.  
  443.     statRec->xOffSent = gGlobals->serStat.xOffSent;  
  444.  
  445.     //    is there a pending read request? 
  446.  
  447.     statRec->rdPend = (gGlobals->pbIn != nil);
  448.  
  449.     //    is there a pending write request?
  450.  
  451.     statRec->wrPend = (gGlobals->pbOut != nil);
  452.  
  453.     //    cts & xOff output flow control hold flags
  454.  
  455.     statRec->ctsHold = false;                    // always false for now?
  456.     statRec->xOffHold = gGlobals->serStat.xOffHold; 
  457.     
  458. }
  459.  
  460. /************************************************************************************/
  461. //
  462. //    HAL_GetBuffer
  463. //
  464. //    status routine computes & returns the number of bytes pending in the receive buffer 
  465. //
  466. /************************************************************************************/
  467.  
  468. UInt32 HAL_GetBuffer(void)
  469. {
  470.     SInt32        count;
  471.     
  472. //    TraceMessage(0,kCRMName"- Entering HAL_GetBuffer");
  473.     
  474.     count = ((SInt32)gGlobals->inBufEndIndex - (SInt32)gGlobals->inBufStartIndex);
  475.     
  476.     if ( count < 0 ) 
  477.         count += gGlobals->inBufLen;
  478.     
  479.     return count;
  480. }
  481.  
  482. /************************************************************************************/
  483. //
  484. //    HAL_SetDTERate
  485. //
  486. /************************************************************************************/
  487.  
  488. UInt16 HAL_SetDTERate(UInt32 baudRate)
  489. {
  490.  
  491.     TraceMessage(0,kCRMName"- Entering HAL_SetDTERate");
  492.     
  493.     //    validate the requested baud rate
  494.     
  495.     if (baudRate)
  496.     {
  497.         if (baudRate > kMaxBaudRate)
  498.             baudRate = kMaxBaudRate;
  499.             
  500.         gGlobals->baudRate = baudRate;
  501.     } else {
  502.         baudRate = gGlobals->baudRate;
  503.     }
  504.     
  505.     USBSetBaudRate(baudRate);
  506.     
  507.     //    return actual baud rate used (this is historical)
  508.  
  509.     return baudRate;
  510. }
  511.  
  512. /************************************************************************************/
  513. //
  514. //    HAL_SetParity
  515. //
  516. //    Assigns parity error replacement character and alternate replacment character.
  517. //    if peChar is zero then no parity error character substitution.
  518. //    This is a stub for now
  519. //
  520. /************************************************************************************/
  521.  
  522. void HAL_SetParity(Boolean alt, char peChar, char peAltChar)
  523. {
  524. #pragma unused (alt, peChar, peAltChar)
  525.  
  526.     TraceMessage(0,kCRMName"- Entering HAL_SetParity");
  527.  
  528. }
  529.  
  530. /************************************************************************************/
  531. //
  532. //    HAL_FillReadRequest
  533. //
  534. //    Attempts to copy requested bytes from the internal serial buffer into request 
  535. //    parameter block.
  536. //
  537. /************************************************************************************/
  538.  
  539. OSErr HAL_FillReadRequest(IOParam *pb)
  540. {
  541.     OSErr    result;
  542.     UInt16    endIndex;
  543.     UInt16    startIndex;
  544.  
  545.     TraceMessage(0,kCRMName"- Entering HAL_FillReadRequest");
  546.  
  547.     result = 1;
  548.     while (result > noErr)
  549.     {
  550.  
  551.         //    this can be interrupted to add data to the internal buffer
  552.         //    so we update inBufStartIndex and inBufEndIndex each time
  553.         //    if there is nothing in the input buffer, leave quietly
  554.  
  555.         endIndex = gGlobals->inBufEndIndex;
  556.         startIndex = gGlobals->inBufStartIndex;
  557.         
  558.         if (startIndex == endIndex) 
  559.             break;
  560.  
  561.         //    copy byte into read request buffer and bump actual count
  562.  
  563.         pb->ioBuffer[pb->ioActCount] = gGlobals->inBufPtr[startIndex];
  564.         pb->ioActCount++;
  565.  
  566.         //    now update internal buffer inBufStartIndex
  567.  
  568.         startIndex++;
  569.         
  570.         if (startIndex >= gGlobals->inBufLen) 
  571.             startIndex = 0;
  572.             
  573.         gGlobals->inBufStartIndex = startIndex;
  574.  
  575.         //    lastly, check if we've satisfied the request
  576.  
  577.         if (pb->ioReqCount <= pb->ioActCount)
  578.             result = noErr;
  579.     }
  580.  
  581.     return result;
  582. }
  583.  
  584. /************************************************************************************/
  585. //
  586. //    HAL_EnableSerialDevice
  587. //
  588. //    Called once at driver open time to configure the hardware and get things going etc.
  589. //
  590. /************************************************************************************/
  591.  
  592. void HAL_EnableSerialDevice(void)
  593. {    
  594.     
  595.     TraceMessage(0,kCRMName"- Entering HAL_EnableSerialDevice");
  596.     
  597.     USBSetRTSState(1);
  598.     USBSetDTRState(1);
  599.     
  600.     USBSetControlLineState();
  601.     
  602.     HAL_SetDTERate(0);
  603.  
  604.     // Start the read mechanism
  605.     
  606.     USBStartReadPolling();
  607.     
  608. }
  609.  
  610. /************************************************************************************/
  611. //
  612. //    HAL_DisableSerialDevice
  613. //
  614. //    Called once when the driver is closed to shut things down
  615. //
  616. /************************************************************************************/
  617.  
  618. void HAL_DisableSerialDevice(void)
  619. {
  620.     
  621.     TraceMessage(0,kCRMName"- Entering HAL_DisableSerialDevice");
  622.  
  623.     USBStopReadPolling();
  624.  
  625.     USBSetRTSState(0);
  626.     USBSetDTRState(0);
  627.     
  628.     USBSetControlLineState();
  629.     
  630. }
  631.  
  632. /************************************************************************************/
  633. //
  634. //    HAL_InputFlowControl
  635. //
  636. //    Handles hardware (dtr or rts) and software (xon / xoff) input flow control
  637. //    This is a stub for now
  638. //
  639. /************************************************************************************/
  640.  
  641. void HAL_InputFlowControl(void)
  642. {
  643.  
  644.     TraceMessage(0,kCRMName"- Entering HAL_InputFlowControl");
  645.  
  646. }
  647.  
  648. /************************************************************************************/
  649. //
  650. //    HAL_EnableInput
  651. //
  652. //    Sets the DTR state
  653. //    This is a stub for now
  654. //
  655. /************************************************************************************/
  656.  
  657. void HAL_EnableInput(Boolean enable)
  658. {
  659. #pragma unused (enable)
  660.  
  661.     TraceMessage(0,kCRMName"- Entering HAL_EnableInput");
  662.  
  663. }
  664.  
  665. /************************************************************************************/
  666. //
  667. //    HAL_EnableOutput
  668. //
  669. //    Handles output flow control
  670. //    This is a stub for now
  671. //
  672. /************************************************************************************/
  673.  
  674. void HAL_EnableOutput(void)
  675. {
  676.  
  677.     TraceMessage(0,kCRMName"- Entering HAL_EnableOutput");
  678.     
  679. }
  680.  
  681. /************************************************************************************/
  682. //
  683. //    HAL_DoOpenSession
  684. //
  685. //    Process an OpenDriver request to the stub drivers
  686. //
  687. /************************************************************************************/
  688.  
  689. OSErr HAL_DoOpenSession(void)
  690. {
  691.  
  692.     OSErr        err;
  693.     LineParms    Line_Coding;
  694.     
  695.     TraceMessage(0,kCRMName"- Entering HAL_DoOpenSession");
  696.     
  697.     // only allow one open session
  698.     
  699.     if (gGlobals->openSession)
  700.         return openErr;
  701.         
  702.     //    reset internal indexes, buffers, etc.
  703.     
  704.     err = HAL_SetInputBuffer(nil, 0);
  705.     if (err)
  706.         return openErr;
  707.     
  708.     //  since we've cleared the buffer to zero initially we have to explicitly
  709.     //  initialize the baudRate
  710.     
  711.     gGlobals->baudRate = kMaxBaudRate;
  712.     
  713.     //    reset default values for other variables
  714.  
  715.     gGlobals->xOnOffChar = 0;
  716.     gGlobals->peChar = 0;
  717.     gGlobals->peAltChar = 0;
  718.  
  719.     //    reset handshake default values as per scc serial driver
  720.  
  721.     gGlobals->serShk.fXOn = 0;
  722.     gGlobals->serShk.fCTS = 1;
  723.     gGlobals->serShk.xOn = 0;
  724.     gGlobals->serShk.xOff = 0;
  725.     gGlobals->serShk.evts = 0;
  726.     gGlobals->serShk.fInX = 0;
  727.     gGlobals->serShk.fDTR = 1;
  728.  
  729.     //    reset serial status record
  730.  
  731.     gGlobals->serStat.cumErrs = 0;
  732.     gGlobals->serStat.xOffSent = 0;
  733.     gGlobals->serStat.rdPend = 0;
  734.     gGlobals->serStat.wrPend = 0;
  735.     gGlobals->serStat.ctsHold = 0;
  736.     gGlobals->serStat.xOffHold = 0;
  737.     
  738.     // Line coding structure
  739.     
  740.     Line_Coding.DTERate1 = 0;            // gets handled later with
  741.     Line_Coding.DTERate2 = 0;            // value from gGlobals->baudRate
  742.     Line_Coding.CharFormat = k1StopBit;
  743.     Line_Coding.ParityType = kNoParity;
  744.     Line_Coding.DataBits = k8DataBits;
  745.     
  746.     InitLineCoding(Line_Coding);
  747.     
  748.     //    Let's get started
  749.     
  750.     HAL_EnableSerialDevice();
  751.     
  752.     // we now have an open session
  753.     
  754.     gGlobals->openSession = true;
  755.         
  756.     return noErr;
  757. }
  758.  
  759. /************************************************************************************/
  760. //
  761. //    HAL_DoCloseSession
  762. //
  763. //    Process a CloseDriver request to the stub drivers
  764. //
  765. /************************************************************************************/
  766.  
  767. OSErr HAL_DoCloseSession(void)
  768. {
  769.  
  770.     TraceMessage(0,kCRMName"- Entering HAL_DoCloseSession");
  771.  
  772.     HAL_DisableSerialDevice();
  773.             
  774.     //    reset internal indexes, buffers, etc. - this
  775.     //    is important for vm to unhold memory on any
  776.     //    buffer the client may have requested earlier
  777.     
  778.     HAL_SetInputBuffer(nil, 0);
  779.                     
  780.     // we no longer have an open session
  781.         
  782.     gGlobals->openSession = false;
  783.  
  784.     return noErr;
  785. }
  786.  
  787. /************************************************************************************/
  788. //
  789. //    HAL_ControlExtend
  790. //
  791. //    User extensions to control
  792. //
  793. /************************************************************************************/
  794.  
  795. OSErr HAL_ControlExtend(ParmBlkPtr pb)
  796. {
  797.  
  798.     TraceMessage(0,kCRMName"- Entering HAL_ControlExtend");
  799.  
  800.     if (pb->cntrlParam.csCode == kpciGetDCD)
  801.     {
  802.         ((char *)(pb->cntrlParam.csParam))[6] = USBGetDCDValue();
  803.         return noErr;
  804.     }
  805.     
  806.     return controlErr;
  807. }
  808.  
  809. /************************************************************************************/
  810. //
  811. //    HAL_StatusExtend
  812. //
  813. //    User extensions to status
  814. //
  815. /************************************************************************************/
  816.  
  817. OSErr HAL_StatusExtend(ParmBlkPtr pb)
  818. {
  819. #pragma unused (pb)
  820.  
  821.     TraceMessage(0,kCRMName"- Entering HAL_StatusExtend");
  822.     
  823.     return statusErr;
  824. }
  825.  
  826. /************************************************************************************/
  827. //
  828. //    HAL_ShimInput
  829. //
  830. //    Handles the coordination of input and the requestors buffer.
  831. //
  832. /************************************************************************************/
  833.  
  834. void HAL_ShimInput(UInt8 *buf, UInt32 count)
  835. {
  836.     IOParam                 *pb;
  837.     OSErr                    result;
  838.     register UInt16            nextIndex;
  839.     register unsigned char    rcvByte;
  840.     unsigned char            cumErrs;
  841.     
  842.     TraceMessage(0,kCRMName"- Entering ShimInput");
  843.         
  844.     //    set return result to incomplete
  845.  
  846.     result = 1;
  847.     cumErrs = 0;
  848.  
  849.     while (count--)
  850.     {
  851.  
  852.         //  handle reading of data available in the hardware receive buffer
  853.         
  854.         rcvByte = *buf++;
  855.                             
  856.         //    compute index into our input buffer
  857.  
  858.         nextIndex = gGlobals->inBufEndIndex + 1;
  859.         if ( nextIndex >= gGlobals->inBufLen ) 
  860.             nextIndex = 0;
  861.             
  862.         //    stuff the character into the input buffer and update the index
  863.  
  864.         gGlobals->inBufPtr[gGlobals->inBufEndIndex] = rcvByte;
  865.         gGlobals->inBufEndIndex = nextIndex;
  866.  
  867.         //    check for input buffer overflow
  868.  
  869.         if (gGlobals->inBufEndIndex == gGlobals->inBufStartIndex)
  870.         {
  871.             //    mark that we've had an overrun
  872.  
  873.             gGlobals->serStat.cumErrs |= swOverrunErr;
  874.             cumErrs |= swOverrunErr;
  875.                 
  876.             //    drop oldest character from our internal buffer
  877.  
  878.             gGlobals->inBufStartIndex++;
  879.             if (gGlobals->inBufStartIndex >= gGlobals->inBufLen)
  880.                 gGlobals->inBufStartIndex = 0;
  881.                 
  882.             //    we've had a software overrun -- we quit now and let the
  883.             //    client get a chance to read in the existing bytes -- 
  884.         }
  885.         
  886.         //    check for an outstanding read request
  887.         
  888.         pb = (IOParam *)gGlobals->pbIn;
  889.         if (pb)
  890.         {
  891.             //    copy bytes from input buffer into pb read buffer
  892.             //    (result is either 1=incomplete or 0=complete)
  893.     
  894.             result = HAL_FillReadRequest(pb);
  895.             
  896.             //    handle errors that cause read aborts
  897.             
  898.             if (cumErrs & gGlobals->serShk.errs) 
  899.                 result = rcvrErr;
  900.             
  901.             //    if we have fulfilled this read request, we
  902.             //  need to call IOCommandIsComplete on it
  903.             //  and continue processing with the next request
  904.             
  905.             if ( result <= noErr )
  906.             {
  907.                 gGlobals->pbIn = nil;
  908.                 ShimIOComplete((union ParamBlockRec *)pb, result);
  909. //                break;
  910.             }
  911.         }
  912.     }
  913.     
  914.     // clean up after ourselves
  915. //    if (result <= noErr)
  916. //        ShimIOComplete((union ParamBlockRec *)pb, result);
  917. }